package com.zmx.core.server;

import com.zmx.core.config.MarshallingCodeCFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @Description: 服务端，显示当前可用定时任务节点
 * @ClassName: Server
 * @Author zhaomxr
 * @Date 2021-12-14 16:14
 */
@Slf4j
public final class Server {

    private int port;
    private String username;
    private String password;
    private String secret;

    public Server(int port, String username, String password, String secret) {
        this.port = port;
        this.username = username;
        this.password = password;
        this.secret = secret;
    }

    public void start() {
        try {
            Thread thread = new Thread(new ServerThread());
            thread.setDaemon(true);
            thread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class ServerThread implements Runnable {

        @Override
        public void run() {
            try {
                log.info("Server Channel begin open! port:{} username:{}", port, password);
                EventLoopGroup pGroup = new NioEventLoopGroup();
                EventLoopGroup cGroup = new NioEventLoopGroup();

                ServerBootstrap b = new ServerBootstrap();
                b.group(pGroup, cGroup).channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_BACKLOG, 1024)
                        //设置日志
                        .handler(new LoggingHandler(LogLevel.INFO))
                        .childHandler(new ChannelInitializer<SocketChannel>() {

                            @Override
                            protected void initChannel(SocketChannel sc) throws Exception {
                                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
                                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
                                sc.pipeline().addLast(new ServerHandler(username, password, secret));
                            }
                        });

                ChannelFuture cf = b.bind(port).sync();
                cf.channel().closeFuture().sync();
                pGroup.shutdownGracefully();
                cGroup.shutdownGracefully();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
